// models/grid.model.ts
import { RowDefinition } from './row-column.model';
import { ColumnDefinition } from './row-column.model';
import { CellDefinition } from './cell.model';

/**
 * 网格布局和单元格集合的定义
 */
export class GridDefinition {
  rowCount: number = 3;
  colCount: number = 3;
  cellHeight: number = 1;
  cellWidth: number = 1;

  /**
   * 存储所有单元格定义。
   * 使用 Map 是为了方便通过 'rowIndex-colIndex' 快速查找。
   * 也可以用二维数组 CellDefinition[][]，初始化时填充。
   */
  cells: Map<string, CellDefinition> = new Map();
  /** 存储行定义 */
  rows: RowDefinition[] = [];
  /** 存储列定义 */
  cols: ColumnDefinition[] = [];

  constructor(initial?: Partial<GridDefinition>) {
    Object.assign(this, initial);
    this.initializeGrid();
  }

  /**
   * 初始化或重置网格单元格、行和列的定义
   */
  public initializeGrid(): void {
    this.cells.clear();
    this.rows = [];
    this.cols = [];

    for (let i = 0; i < this.rowCount; i++) {
      this.rows.push(new RowDefinition(i, this.cellHeight));
    }
    for (let j = 0; j < this.colCount; j++) {
      this.cols.push(new ColumnDefinition(j, this.cellWidth));
    }

    for (let i = 0; i < this.rowCount; i++) {
      for (let j = 0; j < this.colCount; j++) {
        const cell = new CellDefinition(i, j, this.cellWidth, this.cellHeight);
        this.cells.set(cell.key, cell);
      }
    }
  }

  /**
   * 获取指定位置的单元格，如果不存在则创建（理论上应该总存在于初始化后）
   */
  public getCell(
    rowIndex: number,
    colIndex: number
  ): CellDefinition | undefined {
    return this.cells.get(`${rowIndex}-${colIndex}`);
  }

  /**
   * 更新行数
   */
  public updateRowCount(newCount: number): void {
    if (newCount === this.rowCount) return;

    if (newCount < this.rowCount) {
      // 减少行
      // 删除多余的行定义
      this.rows.splice(newCount);
      // 删除多余的单元格
      const newCells = new Map<string, CellDefinition>();
      this.cells.forEach((cell) => {
        if (cell.rowIndex < newCount) {
          newCells.set(cell.key, cell);
        }
      });
      this.cells = newCells;
      // TODO: 处理因行减少导致的合并单元格问题 (简化：暂不处理复杂情况，或提示用户)
    } else {
      // 增加行
      for (let i = this.rowCount; i < newCount; i++) {
        this.rows.push(new RowDefinition(i, this.cellHeight));
        for (let j = 0; j < this.colCount; j++) {
          if (!this.getCell(i, j)) {
            const cell = new CellDefinition(
              i,
              j,
              this.cellWidth,
              this.cellHeight
            );
            this.cells.set(cell.key, cell);
          }
        }
      }
    }
    this.rowCount = newCount;
    // 需要重新验证合并单元格的有效性
    this.validateMerges();
  }

  /**
   * 更新列数
   */
  public updateColCount(newCount: number): void {
    if (newCount === this.colCount) return;

    if (newCount < this.colCount) {
      // 减少列
      this.cols.splice(newCount);
      const newCells = new Map<string, CellDefinition>();
      this.cells.forEach((cell) => {
        if (cell.colIndex < newCount) {
          newCells.set(cell.key, cell);
        }
      });
      this.cells = newCells;
    } else {
      // 增加列
      for (let j = this.colCount; j < newCount; j++) {
        this.cols.push(new ColumnDefinition(j, this.cellWidth));
        for (let i = 0; i < this.rowCount; i++) {
          if (!this.getCell(i, j)) {
            const cell = new CellDefinition(
              i,
              j,
              this.cellWidth,
              this.cellHeight
            );
            this.cells.set(cell.key, cell);
          }
        }
      }
    }
    this.colCount = newCount;
    this.validateMerges();
  }

  /**
   * 合并单元格
   * @param r1 起始行
   * @param c1 起始列
   * @param r2 结束行
   * @param c2 结束列
   */
  public mergeCells(r1: number, c1: number, r2: number, c2: number): boolean {
    const masterRow = Math.min(r1, r2);
    const masterCol = Math.min(c1, c2);
    const endRow = Math.max(r1, r2);
    const endCol = Math.max(c1, c2);

    const rowSpan = endRow - masterRow + 1;
    const colSpan = endCol - masterCol + 1;

    if (rowSpan <= 1 && colSpan <= 1) return false; // 无需合并

    // 检查选区内是否已有其他合并单元格的主单元格 (简单检查)
    for (let i = masterRow; i <= endRow; i++) {
      for (let j = masterCol; j <= endCol; j++) {
        const cell = this.getCell(i, j);
        if (
          cell &&
          (cell.rowSpan > 1 || cell.colSpan > 1 || cell.isMergedSlave)
        ) {
          // 如果选区内有其他合并单元格或被合并的单元格，需要先取消它们
          // 为简化，这里可以提示用户或自动取消（复杂，暂不实现自动取消）
          console.warn(
            'Cannot merge: selection overlaps with existing merged cells. Unmerge them first.'
          );
          return false;
        }
      }
    }

    const masterCell = this.getCell(masterRow, masterCol);
    if (!masterCell) return false;

    masterCell.rowSpan = rowSpan;
    masterCell.colSpan = colSpan;
    masterCell.isMergedSlave = false; // 主单元格不是 slave

    for (let i = masterRow; i <= endRow; i++) {
      for (let j = masterCol; j <= endCol; j++) {
        if (i === masterRow && j === masterCol) continue;
        const slaveCell = this.getCell(i, j);
        if (slaveCell) {
          slaveCell.isMergedSlave = true;
          slaveCell.mergedMaster = { rowIndex: masterRow, colIndex: masterCol };
          slaveCell.rowSpan = 1; // 被合并的单元格自身span为1
          slaveCell.colSpan = 1;
        }
      }
    }
    return true;
  }

  /**
   * 取消合并单元格
   * @param rowIndex 任意在合并区域内的单元格行索引
   * @param colIndex 任意在合并区域内的单元格列索引
   */
  public unmergeCells(rowIndex: number, colIndex: number): boolean {
    let masterCellDef = this.getCell(rowIndex, colIndex);
    if (!masterCellDef) return false;

    if (masterCellDef.isMergedSlave && masterCellDef.mergedMaster) {
      masterCellDef = this.getCell(
        masterCellDef.mergedMaster.rowIndex,
        masterCellDef.mergedMaster.colIndex
      );
      if (!masterCellDef) return false;
    }

    if (masterCellDef.rowSpan <= 1 && masterCellDef.colSpan <= 1) return false; // 不是合并单元格

    const startRow = masterCellDef.rowIndex;
    const startCol = masterCellDef.colIndex;
    const endRow = startRow + masterCellDef.rowSpan - 1;
    const endCol = startCol + masterCellDef.colSpan - 1;

    masterCellDef.rowSpan = 1;
    masterCellDef.colSpan = 1;

    for (let i = startRow; i <= endRow; i++) {
      for (let j = startCol; j <= endCol; j++) {
        const cell = this.getCell(i, j);
        if (cell) {
          cell.isMergedSlave = false;
          cell.mergedMaster = undefined;
          // 保留它们原有的内容和样式，或重置为默认
        }
      }
    }
    return true;
  }

  /**
   * 当行列数变化后，校验并调整合并单元格
   */
  private validateMerges(): void {
    const cellsToUnmerge: Array<{ r: number; c: number }> = [];
    this.cells.forEach((cell) => {
      if (!cell.isMergedSlave && (cell.rowSpan > 1 || cell.colSpan > 1)) {
        const endRow = cell.rowIndex + cell.rowSpan - 1;
        const endCol = cell.colIndex + cell.colSpan - 1;
        if (endRow >= this.rowCount || endCol >= this.colCount) {
          // 合并区域超出现有边界，需要处理
          // 简化处理：直接取消这个合并
          cellsToUnmerge.push({ r: cell.rowIndex, c: cell.colIndex });
        } else {
          // 重新标记slaves，确保它们没被删除
          for (let i = cell.rowIndex; i <= endRow; i++) {
            for (let j = cell.colIndex; j <= endCol; j++) {
              if (i === cell.rowIndex && j === cell.colIndex) continue;
              const slaveCell = this.getCell(i, j);
              if (slaveCell) {
                slaveCell.isMergedSlave = true;
                slaveCell.mergedMaster = {
                  rowIndex: cell.rowIndex,
                  colIndex: cell.colIndex,
                };
              } else {
                // slave被删除了，这理论上不应该发生，因为我们先调整了行列再校验
                // 但如果发生了，也意味着这个合并块不完整，需要取消
                if (
                  !cellsToUnmerge.find(
                    (c) => c.r === cell.rowIndex && c.c === cell.colIndex
                  )
                ) {
                  cellsToUnmerge.push({ r: cell.rowIndex, c: cell.colIndex });
                }
              }
            }
          }
        }
      } else if (cell.isMergedSlave && cell.mergedMaster) {
        const master = this.getCell(
          cell.mergedMaster.rowIndex,
          cell.mergedMaster.colIndex
        );
        if (
          !master ||
          (master.rowSpan === 1 &&
            master.colSpan === 1) /* master不再是合并单元格了 */
        ) {
          cell.isMergedSlave = false;
          cell.mergedMaster = undefined;
        }
      }
    });
    cellsToUnmerge.forEach((coords) => this.unmergeCells(coords.r, coords.c));
  }

  /**
   * 设置行高
   */
  public setRowHeight(rowIndex: number, height: number): void {
    if (this.rows[rowIndex]) {
      this.rows[rowIndex].height = Math.max(10, height); // 最小高度
    }
  }

  /**
   * 设置列宽
   */
  public setColWidth(colIndex: number, width: number): void {
    if (this.cols[colIndex]) {
      this.cols[colIndex].width = Math.max(20, width); // 最小宽度
    }
  }

  /**
   * 获取用于渲染的单元格二维数组
   * 考虑了 isMergedSlave 的单元格不渲染
   */
  public getRenderableCells(): CellDefinition[][] {
    const table: CellDefinition[][] = [];
    for (let i = 0; i < this.rowCount; i++) {
      const row: CellDefinition[] = [];
      for (let j = 0; j < this.colCount; j++) {
        const cell = this.getCell(i, j);
        if (cell && !cell.isMergedSlave) {
          row.push(cell);
        }
        // isMergedSlave 的单元格不推入，因为它们会被主单元格的 rowspan/colspan覆盖
      }
      table.push(row);
    }
    return table;
  }
}
